// 文件：Assets/Editor/FolderIconManager.cs
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using System.Reflection;

public class FolderIconManager : EditorWindow
{
    [System.Serializable]
    public class IconMapping
    {
        public string targetGUID;
        public string iconGUID;
    }

    [System.Serializable]
    public class MappingList
    {
        public List<IconMapping> list = new List<IconMapping>();
    }

    public const string kEditorPrefsKey = "FolderIconManager_Mappings";

    static MethodInfo s_SetIcon;
    private List<IconMapping> mappings;
    private Vector2 scrollPos;

    [MenuItem("Tools/Folder Icon Manager")]
    public static void OpenWindow()
    {
        GetWindow<FolderIconManager>("Folder Icon Manager");
    }

    [MenuItem("Assets/Folder Icon/Change Icon...", false, 1000)]
    static void ChangeIconMenu()
    {
        if (Selection.activeObject != null)
            IconPickerWindow.ShowPicker(Selection.activeObject);
    }

    [MenuItem("Assets/Folder Icon/Change Icon...", true)]
    static bool ChangeIconValidate()
    {
        return Selection.activeObject != null;
    }

    static FolderIconManager()
    {
        s_SetIcon = typeof(EditorGUIUtility)
            .GetMethod("SetIconForObject", BindingFlags.Static | BindingFlags.NonPublic);
        EditorApplication.delayCall += LoadMappingsAndApply;
    }

    void OnEnable()
    {
        LoadMappings();
    }

    void OnGUI()
    {
        if (mappings == null) LoadMappings();

        EditorGUILayout.HelpBox("拖入资源（文件或文件夹）+贴图，点击 Save & Apply 后生效。", MessageType.Info);
        scrollPos = EditorGUILayout.BeginScrollView(scrollPos);

        for (int i = 0; i < mappings.Count; i++)
        {
            var map = mappings[i];
            EditorGUILayout.BeginHorizontal();

            // 目标对象
            var targetPath = AssetDatabase.GUIDToAssetPath(map.targetGUID);
            Object targetObj = string.IsNullOrEmpty(targetPath)
                ? null
                : AssetDatabase.LoadAssetAtPath<Object>(targetPath);
            targetObj = EditorGUILayout.ObjectField(targetObj, typeof(Object), false, GUILayout.Width(200));

            // 图标贴图
            var iconPath = AssetDatabase.GUIDToAssetPath(map.iconGUID);
            Texture2D iconObj = string.IsNullOrEmpty(iconPath)
                ? null
                : AssetDatabase.LoadAssetAtPath<Texture2D>(iconPath);
            iconObj = (Texture2D)EditorGUILayout.ObjectField(iconObj, typeof(Texture2D), false, GUILayout.Width(80));

            // 更新 GUID
            map.targetGUID = targetObj != null
                ? AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(targetObj))
                : string.Empty;
            map.iconGUID = iconObj != null
                ? AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(iconObj))
                : string.Empty;

            if (GUILayout.Button("–", GUILayout.Width(24)))
                mappings.RemoveAt(i--);

            EditorGUILayout.EndHorizontal();
        }

        EditorGUILayout.EndScrollView();
        EditorGUILayout.Space();

        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("Add Entry")) mappings.Add(new IconMapping());
        if (GUILayout.Button("Clear All")) mappings.Clear();
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.Space();

        if (GUILayout.Button("Save & Apply", GUILayout.Height(30)))
        {
            SaveMappings();
            ApplyMappings();
            // 立刻刷新覆盖图标
            FolderIconOverride.ReloadIcons();
        }
    }

    public void LoadMappings()
    {
        var json = EditorPrefs.GetString(kEditorPrefsKey, "");
        if (string.IsNullOrEmpty(json))
            mappings = new List<IconMapping>();
        else
        {
            var wrapper = JsonUtility.FromJson<MappingList>(json);
            mappings = wrapper?.list ?? new List<IconMapping>();
        }
    }

    public void SaveMappings()
    {
        var wrapper = new MappingList { list = mappings };
        EditorPrefs.SetString(kEditorPrefsKey, JsonUtility.ToJson(wrapper));
    }

    public static void LoadMappingsAndApply()
    {
        var json = EditorPrefs.GetString(kEditorPrefsKey, "");
        if (string.IsNullOrEmpty(json)) return;
        var wrapper = JsonUtility.FromJson<MappingList>(json);
        if (wrapper?.list == null) return;
        ApplyMappings(wrapper.list);
    }

    public static void ApplyMappings()
    {
        var json = EditorPrefs.GetString(kEditorPrefsKey, "");
        if (string.IsNullOrEmpty(json)) return;
        var wrapper = JsonUtility.FromJson<MappingList>(json);
        if (wrapper?.list == null) return;
        ApplyMappings(wrapper.list);
    }

    public static void ApplyMappings(List<IconMapping> list)
    {
        bool any = false;
        foreach (var map in list)
        {
            if (string.IsNullOrEmpty(map.targetGUID) || string.IsNullOrEmpty(map.iconGUID))
                continue;

            var targetPath = AssetDatabase.GUIDToAssetPath(map.targetGUID);
            var iconPath = AssetDatabase.GUIDToAssetPath(map.iconGUID);
            var targetObj = AssetDatabase.LoadMainAssetAtPath(targetPath);
            var iconObj = AssetDatabase.LoadAssetAtPath<Texture2D>(iconPath);
            if (targetObj == null || iconObj == null)
                continue;

            if (s_SetIcon != null)
            {
                s_SetIcon.Invoke(null, new object[] { targetObj, iconObj });
            }
            else
            {
                var so = new SerializedObject(targetObj);
                so.Update();
                var modeProp = typeof(SerializedObject)
                    .GetProperty("inspectorMode", BindingFlags.NonPublic | BindingFlags.Instance);
                modeProp?.SetValue(so, InspectorMode.Debug, null);
                var iconProp = so.FindProperty("m_Icon");
                if (iconProp != null)
                {
                    iconProp.objectReferenceValue = iconObj;
                    so.ApplyModifiedProperties();
                    EditorUtility.SetDirty(targetObj);
                }
            }
            any = true;
        }

        if (any)
        {
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
            EditorApplication.RepaintProjectWindow();
        }
    }
}

/// <summary>
/// 弹出窗口：选择贴图后立即保存 & 刷新
/// </summary>
public class IconPickerWindow : EditorWindow
{
    private Object targetObj;
    private string targetGUID;
    private Texture2D icon;

    public static void ShowPicker(Object target)
    {
        var wnd = CreateInstance<IconPickerWindow>();
        wnd.titleContent = new GUIContent("Select Icon");
        wnd.targetObj = target;
        wnd.targetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(target));

        var json = EditorPrefs.GetString(FolderIconManager.kEditorPrefsKey, "");
        if (!string.IsNullOrEmpty(json))
        {
            var wrapper = JsonUtility.FromJson<FolderIconManager.MappingList>(json);
            var m = wrapper.list.Find(x => x.targetGUID == wnd.targetGUID);
            if (m != null)
            {
                var path = AssetDatabase.GUIDToAssetPath(m.iconGUID);
                wnd.icon = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
            }
        }

        wnd.ShowUtility();
    }

    void OnGUI()
    {
        EditorGUILayout.LabelField("Target: " + targetObj.name, EditorStyles.boldLabel);
        EditorGUI.BeginChangeCheck();

        icon = (Texture2D)EditorGUILayout.ObjectField("Icon", icon, typeof(Texture2D), false);

        if (EditorGUI.EndChangeCheck())
        {
            // 更新 Prefs
            var json = EditorPrefs.GetString(FolderIconManager.kEditorPrefsKey, "");
            var wrapper = string.IsNullOrEmpty(json)
                ? new FolderIconManager.MappingList()
                : JsonUtility.FromJson<FolderIconManager.MappingList>(json);

            wrapper.list.RemoveAll(x => x.targetGUID == targetGUID);
            if (icon != null)
            {
                wrapper.list.Add(new FolderIconManager.IconMapping
                {
                    targetGUID = targetGUID,
                    iconGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(icon))
                });
            }

            EditorPrefs.SetString(FolderIconManager.kEditorPrefsKey, JsonUtility.ToJson(wrapper));

            // 立即应用 & 刷新覆盖图标
            FolderIconManager.ApplyMappings(wrapper.list);
            FolderIconOverride.ReloadIcons();

            Close();
        }
    }
}
#endif